package org.internna.expensetracker.model.budget;

import java.util.Set;
import java.util.Date;
import java.util.Locale;
import java.util.HashSet;
import java.util.TreeSet;
import java.math.BigDecimal;
import javax.persistence.OneToOne;
import javax.persistence.FetchType;
import javax.persistence.OneToMany;
import javax.persistence.CascadeType;
import javax.validation.constraints.NotNull;
import org.internna.expensetracker.util.DateUtils;
import org.internna.expensetracker.model.Subcategory;
import org.internna.expensetracker.model.security.UserDetails;
import org.springframework.roo.addon.entity.RooEntity;
import org.springframework.roo.addon.javabean.RooJavaBean;
import org.springframework.roo.addon.tostring.RooToString;
import org.springframework.roo.addon.serializable.RooSerializable;

@RooEntity
@RooJavaBean
@RooToString
@RooSerializable
public class Budget {

    private static final long serialVersionUID = -2382519535503835677L;

    @NotNull
    @OneToOne(fetch = FetchType.EAGER)
    private UserDetails owner;

    @OneToMany(cascade = CascadeType.REMOVE, fetch = FetchType.EAGER, mappedBy = "budget")
    private Set<MonthlyBudget> monthlyBudgets = new HashSet<MonthlyBudget>();

    public final Set<MonthlyBudget> getBudgets() {
    	return new TreeSet<MonthlyBudget>(monthlyBudgets);
    }

    public final MonthlyBudget getMonthlyBudget(Date date) {
    	return getMonthlyBudget(DateUtils.getMonth(date));
    }

    public final MonthlyBudget getMonthlyBudget(Integer month) {
    	if (month != null) {
	    	for (MonthlyBudget monthlyBudget : monthlyBudgets) {
	    		if (month.equals(monthlyBudget.getBudgetedMonth())) {
	    			return monthlyBudget;
	    		}
	    	}
    	}
    	return null;
    }

    public final BigDecimal getAlloted(Date date, Locale locale, Subcategory subcategory) {
    	MonthlyBudget budget = getMonthlyBudget(date);
    	return budget != null ? budget.getAlloted(locale, subcategory) : null;
    }

    /**
     * Budget cannot be removed (NOP).
     */
    public void remove() {
        return;
    }

}
